/**
 * 
 */
package core;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

import util.Constants;
import util.NBGStrParser;
import NET.sourceforge.BplusJ.BplusJ.BplusTree;

/**
 * This version is using BTree for indexing, besides RTree for network indexing.
 * 
 * TODO try other B+tree for bulk loading and scanning leaf pages.
 * @author Xiaohui
 * 
 */
public class TimsQPV2 {
	/**
	 * Constructor
	 */
	RoadNetworkIndex roadIndexer;

	public TimsQPV2() {
		roadIndexer = new RoadNetworkIndex();
	}

	public Set<Long> doEdgeSpatialFilter(QueryParser qparser) throws Exception {
		long start = System.currentTimeMillis();
		Set<Long> eidset = roadIndexer.RTreeQuery4Rid(qparser,
				Constants.brNetRTreeFile, Constants.intersection);
		long end = System.currentTimeMillis();
		System.out.println("Intersected edge num: " + eidset.size());
		System.out.println("Spatial filter(ms): " + (end - start));
		return eidset;
	}

	/**
	 * TODO scan leaf pages 
	 * @param eids
	 * @param parser
	 * 
	 * @return
	 * @throws Exception
	 */
	public Set<Integer> doTemporalFilterBTree(QueryParser parser, Set<Long> eids)
			throws Exception {
		// System.out.println("Indexing cpdata with btree...");
		Set<Integer> oidset = new HashSet<Integer>();
		BplusTree btree = BplusTree.ReadOnly(Constants.timsBTreeFile,
				Constants.timsBlockFile);
		StringTokenizer st;
		long start = System.currentTimeMillis();
		for (long eid : eids) {
			for (int t = (int) parser.getStartTime(); t <= (int) parser
					.getEndTime() + 1; t++) {
				if (btree.ContainsKey(eid + "," + t)) {
					String oidstr = btree.get(eid + "," + t);
					
					st = new StringTokenizer(oidstr, ",");
					while (st.hasMoreElements()) {
						oidset.add(Integer.parseInt(st.nextToken()));
					}
				}
			}
		}
		long end = System.currentTimeMillis();
		System.out.println("Temporal filter(ms): " + (end - start));

		return oidset;
	}

	/**
	 * load into a btree with eid+time_point as key, list of oid as val
	 * 
	 * @param NBGFileName
	 */
	public void loadRawDataBTree(String NBGFileName) {
		String sampleKey = Constants.sampleEid + ",1000";
		BplusTree btree;
		BufferedReader in;
		try {
			btree = BplusTree.Initialize(Constants.timsBTreeFile,
					Constants.timsBlockFile, sampleKey.length());
			NBGStrParser parser = new NBGStrParser();

			in = new BufferedReader(new FileReader(NBGFileName));
			String key, val;
			String str;
			int count = 0;
			while ((str = in.readLine()) != null) {
				if (str.startsWith("#")) {
					continue;
				}
				if (count % 10000 == 0) {
					System.out.println("TIMSV2 Loading progress: " + count);
				}
				count++;
				parser.setNBGStr(str);

				key = parser.getRoadid() + "," + parser.getTimepoint();
				if (btree.ContainsKey(key)) {
					val = btree.get(key) + "," + parser.getOid();
				} else {
					val = parser.getOid() + "";
				}
				btree.Set(key, val);
			}
			in.close();
			btree.Commit();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


}
